package com.processor;

import com.entity.TArticle;
import com.entity.TArticleStatus;
import com.service.ArticleService;
import com.service.ArticleStatusService;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import us.codecraft.webmagic.selector.Html;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by del on 16-5-3.
 */
@Component
public class StatisProcessor {

    private static Logger LOG = LoggerFactory.getLogger(StatisProcessor.class);

    private static Boolean WORKING = false;

    @Autowired
    private ArticleService articleService;

    @Autowired
    private ArticleStatusService articleStatusService;

    public void execute(){
        //任务正在执行
        if (WORKING){
            return;
        }
        Integer count = articleService.getCount();
        Integer pageSize = 10;
        Integer i = 0;
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
        LOG.info("开始执行updateArticleStatus,count:{}",count);
        while (count > pageSize * i){
            Integer start = pageSize * i;
            List<TArticle> articleList = articleService.get(start,pageSize);
            for (final TArticle article : articleList){
                fixedThreadPool.execute(new Runnable() {
                    public void run() {
                        process(article);
                        try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                            LOG.error(e.getMessage());
                        }
                    }
                });
            }
            i++;
        }
        fixedThreadPool.shutdown();
        WORKING = false;
    }

    public void process(TArticle article){
        String url = article.getUrl();
        String regex = "/[0-9]*$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(url);
        if (matcher.find()){

            //创建HttpClientBuilder
            HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
            //HttpClient
            CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
            try {
                //评论数
                Integer commentCount = getCount(url);

                /**获取文章实体**/
                HttpGet httpGet = new HttpGet(url);
                httpGet.setHeader("User-Agent","Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36");
                //执行get请求
                HttpResponse httpResponse = closeableHttpClient.execute(httpGet);
                //获取响应消息实体
                HttpEntity entity = httpResponse.getEntity();
                //响应码
                int statusCode = httpResponse.getStatusLine().getStatusCode();
                //判断响应实体是否为空
                if (statusCode == HttpStatus.SC_OK && entity != null) {
                    String str = EntityUtils.toString(entity,"GBK");
                    Html html = new Html(str);
                    Integer linkView = Integer.valueOf(html.xpath("//span[@class='link_view']/text()").regex("[0-9]*").get());
                    TArticleStatus tArticleStatus = new TArticleStatus();
                    if (linkView != null) {
                        tArticleStatus.setTotayReaderCount(linkView - article.getReadAmount() -1);
                    }
                    if (commentCount != null){
                        tArticleStatus.setTodayCommentCount(commentCount - article.getCommentAmount());
                    }
                    tArticleStatus.setCreateTime(new Date());
                    tArticleStatus.setAid(article.getAid());
                    articleStatusService.add(tArticleStatus);
                    article.setReadAmount(article.getReadAmount() - 1);
                    article.setCommentAmount(article.getCommentAmount());
                    article.setUpdateTime(new Date());
                    articleService.addOrUpdate(article);

                }
            } catch (ClientProtocolException e) {
                LOG.error(e.getMessage());
            } catch (IOException e) {
                LOG.error(e.getMessage());
            } finally {
                try {
                    closeableHttpClient.close();
                } catch (IOException e) {
                    LOG.error(e.getMessage());
                }
            }
        }
    }

    public Integer getCount(String url){
        Integer commentCount = null;
        String regex = "/[0-9]*$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(url);
        if (matcher.find()){
            //创建HttpClientBuilder
            HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
            //HttpClient
            CloseableHttpClient closeableHttpClient = httpClientBuilder.build();

            //文章id
            Integer aid = Integer.valueOf(matcher.group(0).substring(1));
            /**获取文章评论信息**/
            String commentUrlRegex = "http://[^/]*/[^/]*/";
            Pattern commentUrlPattern = Pattern.compile(commentUrlRegex);
            Matcher preStmtCommentMatcher = commentUrlPattern.matcher(url);
            if (preStmtCommentMatcher.find()){
                try {
                    String commentUrl = preStmtCommentMatcher.group(0) + "comment/list/" +aid;
                    System.out.println(commentUrl);
                    HttpGet httpGet = new HttpGet(commentUrl);
                    httpGet.setHeader("User-Agent","Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36");
                    httpGet.setHeader("Cache-Control","max-age=0");
                    //执行get请求
                    HttpResponse httpResponse = closeableHttpClient.execute(httpGet);
                    //获取响应消息实体
                    HttpEntity entity = httpResponse.getEntity();
                    //响应码
                    int statusCode = httpResponse.getStatusLine().getStatusCode();
                    //判断响应实体是否为空
                    if (statusCode == HttpStatus.SC_OK && entity != null) {
                        String comment = EntityUtils.toString(entity,"UTF8");
                        if (StringUtils.isNotBlank(comment)){
                            JSONObject jsonObject = new JSONObject(comment);
                            Integer pageIndex = jsonObject.getJSONObject("page").getInt("PageIndex");
                            Integer pageCount = jsonObject.getJSONObject("page").getInt("PageCount");
                            if (pageIndex >= pageCount){    //没有分页,该页评论数即是评论总数
                                commentCount = jsonObject.getJSONArray("list").length();
                            }
                            else {  //需要分页
                                commentCount = jsonObject.getJSONObject("page").getInt("RecordCount");
                            }
                        }
                        else {
                            return 0;
                        }
                    }
                } catch (ClientProtocolException e) {
                    LOG.error(e.getMessage());
                } catch (IOException e) {
                    LOG.error(e.getMessage());
                } finally {
                    try {
                        closeableHttpClient.close();
                    } catch (IOException e) {
                        LOG.error(e.getMessage());
                    }
                }
            }
        }
        return commentCount;
    }
}
